package com.ruoyi.plugs.blog.common;

import cn.hutool.core.util.URLUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.security.Md5Utils;

import java.util.Map;
import java.util.TreeMap;

/**
 * oauth签名计算和校验工具类
 * Created by user on 2016/1/21.
 */
public class OAuthUtil {
    /**
     * 检查签名是否正确
     *
     * @param map 参数的列表,签名字段的字段名为sign
     * @return 签名正确返回true, 错误返回false
     */
    public static boolean checkSign(Map<String, String> map) {
        String sign = StringUtils.trim(map.get("sign"));
        return StringUtils.isNotEmpty(sign) && sign.equals(calculateSign(map));
    }


    /**
     * 根据要签名的字段和key生成签名
     *
     * @param arr 数据 key在数据中
     * @return 生成的签名字符串, 错误返回""
     */
    public static String calculateSign(Map<String, String> arr) {
        if (arr != null && arr.size() > 0) {
            String key = arr.get("key");
            return calculateSign(arr, key);
        }
        return "";
    }

    /**
     * 根据要签名的字段和key生成签名
     *
     * @param arr 数据
     * @param key key
     * @return 生成的签名字符串, 错误返回""
     */
    public static String calculateSign(Map<String, String> arr, String key) {
        if (arr != null && arr.size() > 0 && StringUtils.isNotEmpty(key)) {
            StringBuilder buff = new StringBuilder();
            Map<String, String> map = new TreeMap<String, String>();
            map.putAll(arr);
            String url = mapToUrlPara(map);
            //System.out.println(buff);
            String signTemp = buff.append(url).append("&key=").append(key).toString();
            //System.out.println(signTemp);
            return Md5Utils.hash(signTemp);
        }
        return "";
    }

    /**
     * 将map转换为url
     *
     * @param map url中的key-value列表
     * @return url形式的字符串, 不包括key, sign两个字段
     */
    public static String mapToUrlPara(Map<String, String> map) {
        if (map != null) {
            StringBuilder sb = new StringBuilder();
            for (Map.Entry<String, String> entry : map.entrySet()) {
                if (!"sign".equals(entry.getKey()) && !"key".equals(entry.getKey()) && StringUtils.isNotEmpty(entry.getValue())) {
                    sb.append(entry.getKey()).append("=").append(URLUtil.encode(entry.getValue())).append("&");
                }
            }
            if (sb.length() > 0 && sb.charAt(sb.length() - 1) == '&') {
                sb.deleteCharAt(sb.length() - 1);
            }
            return sb.toString();
        }
        return "";
    }

}
